package model;

/*
 * The CreditCard class.
 * 
 * @author Abdiel Cabrera
 * 
 * This class holds the info of a credit card.
 */

/**
 * Credit Card class.
 * 
 * @author Abdiel Cabrera.
 * @version 1.0
 * @date Winter 2014
 */
public class CreditCard {

	/** The number of this credit card */
	private String my_number; 
	
	/** The expiration year of this credit card */
	private int my_exp_year;
	
	/** The expiration month of this credit card */
	private int my_exp_month;
	
	/** The signature of this credit card */
	private String my_signature_number; 
	
	/** 
	 * Construct a Credit Card object. 
	 * 
	 * @pre the_number != null
	 * @pre the_number.lenght == 16
	 * @pre the_exp_year != null
	 * @pre the_exp_year =< get(Calendar.YEAR)
	 * @pre the_exp_month != null
	 * @pre the_exp_month > 0 && the_exp_month < 13
	 * @pre the_signature_number != null
	 * @pre the_signature_number.lenght == 3
	 * 
	 * @param the_number The credit card number.
	 * @param the_exp_year The expiration year.
	 * @param the_exp_month The expiration month
	 * @param the_signature_number  The security number in the back.
	 */
	public CreditCard(String the_number, int the_exp_year, int the_exp_month,
			String the_signature_number)
	{
		setMy_number(the_number);
        setMy_exp_year(the_exp_year);
		setMy_exp_month(the_exp_month);
		setMy_signature_number(the_signature_number);
	}

	/**
	 * Returns the number of this credit card.
	 * 
	 * @return the my_number
	 */
	public String getMy_number() {
		return my_number;
	}

	/**
	 * Sets the number of this credit card.
	 * 
	 * @pre the_number != null
	 * @pre the_number.lenght == 16
	 * @param my_number the my_number to set
	 */
	public void setMy_number(String the_number) {
		this.my_number = the_number;
	}

	/**
	 * Returns the expiration year of this credit card.
	 * 
	 * @return the my_exp_year
	 */
	public int getMy_exp_year() {
		return my_exp_year;
	}

	/**
	 * Sets the expiration year of this credit card.
	 * 
	 * @pre the_exp_year != null
	 * @pre the_exp_year =< get(Calendar.YEAR)
	 * @param my_exp_year the my_exp_year to set
	 */
	public void setMy_exp_year(int the_exp_year) {
		this.my_exp_year = the_exp_year;
	}

	/**
	 * Returns the expiration month of this credit card.
	 * 
	 * @return the my_exp_month
	 */
	public int getMy_exp_month() {
		return my_exp_month;
	}

	/**
	 * Sets the expiration month of this credit card.
	 * 
	 * @pre the_exp_month != null
	 * @pre the_exp_month > 0 && the_exp_month < 13
	 * @param my_exp_month the my_exp_month to set
	 */
	public void setMy_exp_month(int the_exp_month) {
		this.my_exp_month = the_exp_month;
	}

	/**
	 * Returns the 3 digits signature number of this credit card.
	 * 
	 * @return the my_signature_number
	 */
	public String getMy_signature_number() {
		return my_signature_number;
	}

	/**
	 * Sets the 3 digits signature number of this credit card.
	 * 
	 * @pre the_signature_number != null
	 * @pre the_signature_number.lenght == 3
	 * @param my_signature_number the my_signature_number to set
	 */
	public void setMy_signature_number(String the_signature_number) {
		this.my_signature_number = the_signature_number;
	}
	
	/**
	 * Check if an specific credit card is valid or not.
	 * Accepted types:  Visa, MasterCard, Discovery
	 * 
	 * @return TRUE if credit card valid
	 *         FALSE otherwise
	 */
	public boolean isValid() {
		boolean answer = true;
		if (my_number.length() != 16) answer = false;
		if (!isNumeric(my_number)) answer = false;
		if (my_exp_year < 14 || my_exp_year > 99) answer = false;
        if (my_exp_month > 12 || my_exp_month < 1) answer = false;
        if (my_exp_year == 14 && my_exp_month < 3) answer = false;
        if (my_signature_number.length() != 3) answer = false;
		if (!isNumeric(my_signature_number)) answer = false;
		return answer;
	}
	
	/**
	 * Returns a String representation of the Credit Card object.
	 * 
	 * @return a String representation.
	 */
	public String toString() {
		String result;
		result = my_number + "~" + my_exp_year + "~"+ my_exp_month + "~" + my_signature_number;
		return result;
	}
	
	// ***** Helper methods *****
	
	/**
	 * Checks if an specific String is numeric.
	 * 
	 * @pre str != null
	 * @param the string to check if is numeric
	 */
	private static boolean isNumeric(String str)  
	{  
	  try  
	  {  
	    @SuppressWarnings("unused")
		double d = Double.parseDouble(str);  
	  }  
	  catch(NumberFormatException nfe)  
	  {  
	    return false;  
	  }  
	  return true;  
	}
}
